package view;

import controller.FileTransferServiceForP2P;
import controller.FileTransferServiceForP4P;
import controller.MainUpdater;
import model.generators.networkGenerators.BarabasiAlbertGenerator;
import net.miginfocom.swing.MigLayout;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;

public class MainFrame extends JFrame {

    private final Label stabilityVal;
    private final Label trafficPctVal;
    private final Label transferVal;
    private final Label hopCountVal;
    private JPanel contentPane;
	private final ButtonGroup buttonGroup = new ButtonGroup();
    private MainUpdater simulation;
    private Thread simulationThread;
    private boolean updateView;

    /**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainFrame frame = new MainFrame();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public MainFrame() {
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setBounds(100, 100, 800, 306);
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException | InstantiationException
				| IllegalAccessException | UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new MigLayout("", "[grow][::200px,grow]", "[grow]"));


		JPanel monitorPanel = new JPanel();
		monitorPanel.setBorder(new TitledBorder(new LineBorder(new Color(0, 0, 0), 1, true), "Monitor", TitledBorder.LEFT, TitledBorder.TOP, null, null));
		contentPane.add(monitorPanel, "cell 0 0,grow");
		monitorPanel.setLayout(null);
		
		JLabel lblStability = new JLabel("Avg. stability: ");
		lblStability.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblStability.setBounds(156, 22, 108, 19);
		monitorPanel.add(lblStability);
		
		JLabel lblTransfer = new JLabel("Avg. transfer: ");
		lblTransfer.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblTransfer.setBounds(157, 85, 107, 19);
		monitorPanel.add(lblTransfer);
		
		JLabel lblAvgHopCount = new JLabel("Avg. Hop count: ");
		lblAvgHopCount.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblAvgHopCount.setBounds(144, 148, 120, 19);
		monitorPanel.add(lblAvgHopCount);
		
		JLabel lblLocalMovementPercentage = new JLabel("Local network traffic percentage: ");
		lblLocalMovementPercentage.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblLocalMovementPercentage.setBounds(10, 207, 254, 19);
		monitorPanel.add(lblLocalMovementPercentage);
		
		stabilityVal = new Label("0.0");
		stabilityVal.setFont(new Font("Simplified Arabic Fixed", Font.PLAIN, 15));
		stabilityVal.setForeground(Color.BLUE);
		stabilityVal.setBounds(364, 22, 81, 30);
		monitorPanel.add(stabilityVal);
		
		transferVal = new Label("0.0");
		transferVal.setFont(new Font("Simplified Arabic Fixed", Font.PLAIN, 15));
		transferVal.setForeground(Color.BLUE);
		transferVal.setBounds(364, 85, 81, 30);
		monitorPanel.add(transferVal);
		
		hopCountVal = new Label("0.0");
		hopCountVal.setFont(new Font("Simplified Arabic Fixed", Font.PLAIN, 15));
		hopCountVal.setForeground(Color.BLUE);
		hopCountVal.setBounds(364, 148, 81, 30);
		monitorPanel.add(hopCountVal);
		
		trafficPctVal = new Label("0.0");
		trafficPctVal.setFont(new Font("Simplified Arabic Fixed", Font.PLAIN, 15));
		trafficPctVal.setForeground(Color.BLUE);
		trafficPctVal.setBounds(364, 207, 81, 30);
		monitorPanel.add(trafficPctVal);
		
		JPanel controlPanel = new JPanel();
		controlPanel.setBorder(new TitledBorder(new LineBorder(new Color(0, 0, 0), 1, true), "Settings", TitledBorder.RIGHT, TitledBorder.TOP, null, null));
		contentPane.add(controlPanel, "cell 1 0,grow");
		controlPanel.setLayout(null);
		
		JPanel algorithmPanel = new JPanel();
		algorithmPanel.setBounds(10, 21, 180, 148);
		algorithmPanel.setPreferredSize(new Dimension(180, 80));
		algorithmPanel.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "Algorithm", TitledBorder.LEADING, TitledBorder.BELOW_TOP, null, null));
		controlPanel.add(algorithmPanel);
		algorithmPanel.setLayout(new GridLayout(0, 1, 0, 0));
		
		final JRadioButton rbP4P = new JRadioButton("P4P (iTracker)");
		rbP4P.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
                simulation = rbP4P.isSelected() ? new MainUpdater(BarabasiAlbertGenerator.generator.getNetwork(), new FileTransferServiceForP4P())
                        : new MainUpdater(BarabasiAlbertGenerator.generator.getNetwork(), new FileTransferServiceForP2P());
			}
		});
		rbP4P.setSelected(true);
        simulation = new MainUpdater(BarabasiAlbertGenerator.generator.getNetwork(), new FileTransferServiceForP4P());
		buttonGroup.add(rbP4P);
		algorithmPanel.add(rbP4P);
		
		JRadioButton rbP2P = new JRadioButton("P2P (Random)");
		buttonGroup.add(rbP2P);
		algorithmPanel.add(rbP2P);
		
		JPanel actionPanel = new JPanel();
		actionPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		actionPanel.setBounds(10, 201, 180, 37);
		actionPanel.setPreferredSize(new Dimension(180, 50));
		controlPanel.add(actionPanel);
		
		JButton btnSimulate = new JButton("Simulate");
		btnSimulate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
                simulationThread = new Thread(simulation);
                simulationThread.start();
                updateView = true;
                viewUpdater();
            }
		});
		actionPanel.add(btnSimulate);
	}

    private void viewUpdater() {

        Thread t  = new Thread(new Runnable() {
            @Override
            public void run() {
                while ( updateView ) {
                    DecimalFormat format = new DecimalFormat("######.##");
                    hopCountVal.setText( format.format(simulation.getFileTransferService().getAverageJumpCount()) );
                    stabilityVal.setText( format.format(simulation.getFileTransferService().getAverageStability()) );
                    trafficPctVal.setText( format.format(simulation.getFileTransferService().getLocalMovementPercent()) );
                    transferVal.setText( format.format(simulation.getFileTransferService().getAverageTransfer()) );
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t.start();
    }
}
